package cn.fx.system.service.impl;

import cn.fx.basic.service.impl.BaseServiceImpl;
import cn.fx.system.domain.Menu;
import cn.fx.system.mapper.MenuMapper;
import cn.fx.system.service.IMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
//查询的方法比较多，使用查询的事务配置
//只读，事务传播机制=SUPPORTS，有我就用，没有事务就不用
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
public class MenuServiceImpl extends BaseServiceImpl<Menu> implements IMenuService {

    @Autowired
    private MenuMapper menuMapper;

    @Override
    @Transactional
    public void save(Menu menu) {
        // 返回自增的主键 id
        menuMapper.save(menu);
        //调用update方法，更新到数据库
        update(menu);
    }

    @Override
    @Transactional
    public void update(Menu menu) {
        //如果没有选择上级部门
        if(menu.getParent_id() == null){
            //dirpath  /id
            Long id = menu.getId();
            //只添加自己的id - 自增长id  设置dirPath
            menu.setUrl("/" + id);

        } else {  //有上级部门
            //通过parent_id获取上级部门dirpath (id)
            Long parent_id = menu.getParent_id();
            //获取上级部门对象
            Menu parentMenu = menuMapper.loadById(parent_id);
            //组装自己的id Url
            menu.setUrl(menu.getUrl() + "/" + menu.getId());

        }

        menuMapper.update(menu);
    }

    @Override
    public List<Menu> menuTree() {
        /*
            1. 一次性查询出所有数据，放到内存中，可以使用map
            2. 从所有部门中获取顶级部门 通过parent_id是否为空
            3. 遍历所有部门 非顶级部门，找自己的上级，并将自己放入上级的children中
        */
        //查询所有
        List<Menu> allMenus = menuMapper.loadAll();

        //准备一个map 每次获取父部门都从这里获取  避免双重for循环
        HashMap<Long, Menu> map = new HashMap<>();

        //把所有数据放入map中 将所有部门装到map中
        for (Menu menu : allMenus){
            map.put(menu.getId(),menu);
        }

        //准备一个list，保存处理之后的数据: 前端需要得到的集合数据 - 部门树
        List<Menu> menuTree = new ArrayList<>();
        for(Menu menu : allMenus){
            //顶级部门
            if(menu.getParent_id() == null){
                menuTree.add(menu);
            } else {
                //不是顶级部门  1.想办法找到当前部门的 父部门  获取parent_id
                Long parent_id = menu.getParent_id();

                //获取上级部门对象: 通过parent_id来找到上级部门, map里面有所有部门信息
                Menu parentMenu = map.get(parent_id);

                //2.将自己装到  父部门 的children中
                parentMenu.getChildren().add(menu);
            }
        }
        //返回部门树
        return menuTree;
    }
}
